package org.mili.ticketeer.ui;

import org.mili.ticketeer.report.ReportEngine;
import org.mili.ticketeer.service.ContactService;
import org.mili.ticketeer.service.MigrationService;
import org.mili.ticketeer.service.ServiceException;
import org.mili.ticketeer.service.ServiceFactory;
import org.mili.ticketeer.ui.contact.ContactPortal;
import org.mili.ticketeer.ui.priority.PriorityPortal;
import org.mili.ticketeer.ui.role.RolePortal;
import org.mili.ticketeer.ui.state.StatePortal;
import org.mili.ticketeer.ui.ticket.TicketPortal;

import javax.swing.*;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;

/**
 */
public class Main {
    private JFrame frame;
    private JMenuBar menuBar;
    private JTabbedPane tabbedPane;
    private Set<String> openTabs = new HashSet<String>();

    private ReportEngine reportEngine = new ReportEngine();

    public Main() {
        init();
        frame = new JFrame("Ticketeer");
        frame.setSize(640, 480);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu menu = new JMenu("Administration");
        menuBar.add(menu);
        addAdministrationReportsMenu(menu);
        addAdministrationContactMenu(menu);
        addAdministrationStateMenu(menu);
        addAdministrationPriorityMenu(menu);
        addAdministrationRoleMenu(menu);
        addAdministrationTicketsMenu(menu);
        addQuitMenu();
        tabbedPane = new JTabbedPane();
        frame.add(tabbedPane);
    }

    private void addQuitMenu() {
        JMenu menu = new JMenu("Exit");
        menu.addMenuListener(new MenuListener() {
            @Override
            public void menuSelected(MenuEvent e) {
                frame.dispose();
            }

            @Override
            public void menuDeselected(MenuEvent e) {
            }

            @Override
            public void menuCanceled(MenuEvent e) {
            }
        });
        menuBar.add(menu);
    }

    private void addAdministrationReportsMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("Create reports");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    reportEngine.start();
                } catch (ServiceException e1) {
                    e1.printStackTrace();
                }
            }
        });
        menu.add(menuItem);
    }

    private void addAdministrationTicketsMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("Tickets");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!openTabs.contains(TicketPortal.class.getSimpleName())) {
                    tabbedPane.addTab(TicketPortal.class.getSimpleName(), new TicketPortal());
                    openTabs.add(TicketPortal.class.getSimpleName());
                }
            }
        });
        menu.add(menuItem);
    }

    private void addAdministrationContactMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("Contacts");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!openTabs.contains(ContactPortal.class.getSimpleName())) {
                    tabbedPane.addTab(ContactPortal.class.getSimpleName(), new ContactPortal());
                    openTabs.add(ContactPortal.class.getSimpleName());
                }
            }
        });
        menu.add(menuItem);
    }

    private void addAdministrationStateMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("States");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!openTabs.contains(StatePortal.class.getSimpleName())) {
                    tabbedPane.addTab(StatePortal.class.getSimpleName(), new StatePortal());
                    openTabs.add(StatePortal.class.getSimpleName());
                }
            }
        });
        menu.add(menuItem);
    }

    private void addAdministrationPriorityMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("Priorities");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!openTabs.contains(PriorityPortal.class.getSimpleName())) {
                    tabbedPane.addTab(PriorityPortal.class.getSimpleName(), new PriorityPortal());
                    openTabs.add(PriorityPortal.class.getSimpleName());
                }
            }
        });
        menu.add(menuItem);
    }

    private void addAdministrationRoleMenu(JMenu menu) {
        JMenuItem menuItem = new JMenuItem("Roles");
        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!openTabs.contains(RolePortal.class.getSimpleName())) {
                    tabbedPane.addTab(RolePortal.class.getSimpleName(), new RolePortal());
                    openTabs.add(RolePortal.class.getSimpleName());
                }
            }
        });
        menu.add(menuItem);
    }

    private void init() {
        try {
            System.out.println("migrate database...");
            ServiceFactory.getService(MigrationService.class).migrate(false);
            System.out.println("    OK.");
        } catch (ServiceException e) {
            halt(e);
        }
    }

    private void halt(ServiceException e) {
        e.printStackTrace();
        System.exit(-1);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main();
            }
        });
    }

}
